﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Utils;
using COFE.Core;
using COFE.Core.Profile;
using COFE.Core.Lister;
using COFE.Core;
using COFE.Core.Logger;
using NUnit.Framework;

namespace COFE.Core
{
    public class UserProfile : IUserProfile
    {
        #region Constructor

        private void init(string userName)
        {
            UserName = userName;
            File = new FileServices(this);
            Directory = new DirectoryServices(this);
            EntryListManager = new EntryListManager(this);
        }

        protected UserProfile(string userName, Func<IUserProfile, IVolumeManager> volumesFunc)
        {
            Assert.IsNotNull(userName);
            Assert.IsNotNull(volumesFunc);

            init(userName);
            Volumes = volumesFunc(this);
        }

        private UserProfile(string userName, bool allVolumes)           
        {
            Assert.IsNotNull(userName);            
            if (allVolumes)
                Volumes = new AllVolumeManager(this);
            else
                Volumes = new VolumeManager(this);
            init(userName);
        }        

        public static IUserProfile Create(string userName, bool allVolumes = true, bool login = true)
        {
            var retVal = new UserProfile(userName, allVolumes);
            if (login)
                COFEShared.UserProfileManager.SetCurrentUserProfile(retVal);
            return retVal;
        }
        

        #endregion

        #region Static Methods

        /// <summary>
        /// Register a factory that create T.
        /// </summary>
        public static void RegisterFactory<T>(IFactory<T> factory)
        {
            FactoryRegister<T>.RegisterFactory(factory.FactoryKey, factory);
        }

        /// <summary>
        /// Find a factory that create T.
        /// </summary>
        public static string FindFactory<T>(IFactory<T> factory)
        {
            return FactoryRegister<T>.FindFactory(factory);
        }

        /// <summary>
        /// Find a factory that create T.
        /// </summary>
        public static IFactory<T> FindFactory<T>(string key)
        {
            return FactoryRegister<T>.Factories[key];
        }

        #endregion


        #region Methods

        #region UserProfile layer
        //public IInternalFileInfoExA CreateFile(IDirectoryLister lister, IPropertyProvider primPropProvider, IPropertyProvider cachePropProvider = null)
        //{
        //    return Volumes.CreateFile(lister, primPropProvider, cachePropProvider);
        //}

        //public IInternalDirectoryInfoExA CreateDirectory(IDirectoryLister lister, IPropertyProvider primPropProvider, IPropertyProvider cachePropProvider = null)
        //{
        //    return Volumes.CreateDirectory(lister, primPropProvider, cachePropProvider);
        //}

        //public IInternalFileSystemInfoExA CreateEntry(IDirectoryLister lister, IPropertyProvider primPropProvider)
        //{
        //    bool isFolder = ((FileAttributes)(primPropProvider.GetCOFEProperty(FileSystemInfoProperties.FileAttributes).Value)
        //                        | FileAttributes.Directory) != 0;
        //    return CreateEntry(lister, primPropProvider, isFolder);
        //}

        //public IInternalFileSystemInfoExA CreateEntry(IDirectoryLister lister, IPropertyProvider primPropProvider, bool isFolder)
        //{
        //    return Volumes.CreateEntry(lister, primPropProvider, isFolder);
        //}

        //public void NotifyFileSystemModified(object sender, FileSystemEventArgsExA args)
        //{
        //    Volumes.NotifyFileSystemModified(sender, args);
        //}

        //public string NewTemp()
        //{
        //    return Volumes.TempManager.NewTemp();
        //}

        //public string GetTempPath(IO.IFileSystemInfo item)
        //{
        //    return Volumes.TempManager.GetTempPath(item);
        //}


        //public void RegisterDirectoryListers(string factoryKey, string listerKey, params string[] parameters)
        //{
        //    Volumes.RegisterDirectoryListers(factoryKey, listerKey, parameters);
        //}

        //public void RegisterDirectoryListers(string secondaryFactoryKey)
        //{
        //    Volumes.RegisterDirectoryListers(secondaryFactoryKey);
        //}

        //public void RegisterDirectoryListers(string listerKey, IDirectoryLister lister)
        //{
        //    Volumes.RegisterDirectoryListers(null, listerKey, lister);
        //}

        //public void RegisterDirectoryListers(string factoryKey, string listerKey, IDirectoryLister lister)
        //{
        //    Volumes.RegisterDirectoryListers(factoryKey, listerKey, lister);
        //}

        //public IVolume FindRegisteredVolume(string listerKey)
        //{
        //    return Volumes.FindRegisteredVolume(listerKey);
        //}

        //public IVolume[] FindRegisteredVolume<T>()
        //{
        //    return Volumes.FindRegisteredVolume<T>();
        //}

        //public IO.IFileSystemInfo ParsePath(string path, string listerKey)
        //{
        //    return ParsePath(COFEPath.FormatFullParseName(listerKey, path));
        //}

        //public IO.IFileSystemInfo ParsePath(string path)
        //{
        //    IFileSystemInfo retVal = TryParsePath(path);
        //    if (retVal == null)
        //        throw new System.IO.FileNotFoundException(path);
        //    return retVal;
        //}

        //public IO.IFileSystemInfo TryParsePath(string path, string listerKey)
        //{
        //    return TryParsePath(COFEPath.FormatFullParseName(listerKey, path)); 
        //}

        //public IO.IFileSystemInfo TryParsePath(string path)
        //{
        //    return PathParser.TryParsePath(path, ParsableType.ParsePath);
        //}

        //public IO.IFileSystemInfo TryLookupPath(string path, string listerKey)
        //{
        //    return TryLookupPath(COFEPath.FormatFullParseName(listerKey, path)); 
        //}

        //public IO.IFileSystemInfo TryLookupPath(string path)
        //{
        //    return PathParser.TryParsePath(path, ParsableType.ParsePathLookup);
        //}
        #endregion

        #endregion

        #region Data

        #endregion

        #region Public Properties

        #region
        //UserProfile layer
        //public string TempPath { get { return Volumes.TempManager.TempPath; } }
        //public Dictionary<string, IVolume> PrimaryVolumes { get { return Volumes.PrimaryVolumes; } }
        //public Dictionary<string, IVolume> SecondaryDirectoryListers { get { return Volumes.SecondaryDirectoryListers; } }
        //public IDirectoryInfo[] RootDirectories { get { return Volumes.RootDirectories; } }
        //public List<IPropertyProviderFactory> SecondaryPropertyProviderFactories { get { return PropertyProviders.SecondaryPropertyProviderFactories; } }
        #endregion

        public string UserName { get; private set; }        
        public IVolumeManager Volumes { get; private set; }                
        public ITempManager TempManager { get { return Volumes.TempManager; } }
        public IEntryListManager EntryListManager { get; protected set; }

        public IFileServices File { get; private set; }
        public IDirectoryServices Directory { get; private set; }

        public IDirectoryInfo ProfileRootDirectory { get { return COFEShared.PathParser.TryParsePath("", ParsableType.ParsePath) as IDirectoryInfo; } }
       

        #endregion





    }
}
